package ch.sv7.tool.dbmanager.db.fix;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import ch.sv7.tool.dbmanager.db.dialect.Dialect;
import ch.sv7.tool.dbmanager.db.dialect.DialectException;
import ch.sv7.tool.dbmanager.db.difference.SchemaDifference;
import ch.sv7.tool.log.Logger;



/**
 * TODO: Document me!
 *
 * @author svt
 *
 */
public abstract class AbstractSchemaFix implements SchemaFix {

	private static final Logger log = Logger.getLogger(AbstractSchemaFix.class);
	
	private Dialect dialect;
	private List differences = new ArrayList();

	public void setDialect(Dialect dialect) {
		this.dialect = dialect;
	}
	
	/**
	 * @return the dialect
	 */
	public Dialect getDialect() {
		return dialect;
	}

	/**
	 * @return the difference
	 */
	public List getFixedDifferences() {
		return differences;
	}

	/**
	 * @param difference the difference to set
	 */
	public void addFixedDifference(SchemaDifference difference) {
		this.differences.add(difference);
	}

	public void addFixedDifferences(List differences){
		this.differences.addAll(differences);
	}
	public boolean equals(Object obj) {
		if (obj instanceof AbstractSchemaFix){
			AbstractSchemaFix other = (AbstractSchemaFix)obj;
			return getDescription().equals(other.getDescription());
		} else {
			return false;
		}
	}


	public int hashCode() {
		return getDescription().hashCode();
	}

	public int compareTo(Object o) {

		if (o instanceof AbstractSchemaFix){
			AbstractSchemaFix fix = (AbstractSchemaFix)o;
			if (getPriority() == fix.getPriority()) {
				return getDescription().compareTo(fix.getDescription());
			} else {
				return getPriority() < fix.getPriority() ? -1 : 1;
			}
		} else {
			return -1;
		}
	}

	public void executeFixing(Connection conn) throws DialectException, SQLException {
		execute(getSQLFix(), conn);
	}	
	
	public void execute(String ddl, Connection conn) throws DialectException, SQLException {
		Statement stmt = conn.createStatement();
			StringTokenizer tokens = new StringTokenizer(ddl, ";");
			while (tokens.hasMoreElements()) {
				String sql = tokens.nextToken();
				try {
					log.debug("Executing:" + sql);
					int result = stmt.executeUpdate(sql);
					log.debug("Result: " + result);
				} catch (SQLException e) {
					if (getDialect().isRealError(e)){
						SchemaFixes.dumpFix(this, System.err);
						log.error("ERROR while executing : " + ddl);
						log.error(e.getMessage());
						throw e;
					} else {
						log.info(e.getMessage());
					}
				}	
			}
	}
	

}
